/*************************************************************************
                           LIVIATcp_server  -  description
                             -------------------
    début                : 22 févr. 2012
    copyright            : (C) 2012 par maxime-chabert
*************************************************************************/

//---------- Réalisation de la classe <LIVIATcpserver> (fichier LIVIATcpserver.cpp) -------

//---------------------------------------------------------------- INCLUDE
//-------------------------------------------------------- Include système
#include <sstream>
#include <boost/bind/bind.hpp>
//------------------------------------------------------ Include personnel
#include "LIVIATcpserver.h"

using namespace std;
using namespace boost;

//------------------------------------------------------------- Constantes

//----------------------------------------------------------------- PUBLIC

//----------------------------------------------------- Méthodes publiques

void LIVIATcp_server::sendRobot( const Robot& robot )
{
	char *message = robotToSend(robot);
	async_write( datas, boost::asio::buffer(message, sizeof(float)*3 + 1), NULL);
}

void LIVIATcp_server::sendGrid( vector<XYGrid> grid )
{
	char *message = gridToSend(grid);

	async_write( datas, boost::asio::buffer(message, sizeof(GRID)*grid.size() + 2), NULL);
}

void LIVIATcp_server::read()
{
	async_read(control, buffer, boost::asio::transfer_at_least(2), boost::bind(&LIVIATcp_server::handler_read,this,
			boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred) );
	//transfer_at_least(2) permet à la lecture d'appeler le handler qd au moins 2 octect ont été transferrés
	// et que la lecture est finie
	//http://www.boost.org/doc/libs/1_49_0/libs/bind/bind.html#with_functions pour bind
}
//------------------------------------------------- Surcharge d'opérateurs

//-------------------------------------------- Constructeurs - destructeur

LIVIATcp_server::LIVIATcp_server(boost::asio::io_service& io, int portIp, string ip)
: accept(io, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(ip), portIp)),
  control(io)
{
	accept.async_accept(control ,boost::bind(&LIVIATcp_server::handle_accept,this,
			boost::asio::placeholders::error));
	address = control.remote_endpoint();
}

LIVIATcp_server::~LIVIATcp_server() {
}


//------------------------------------------------------------------ PRIVE

//----------------------------------------------------- Méthodes protégées

void LIVIATcp_server::handle_accept(const boost::system::error_code& error)
{
	if( !error )
	{
		cout << "new client" << endl;
		address = control.remote_endpoint();
	}
	else
	{
		cout << "error acceptation" << endl;
	}
}

char *LIVIATcp_server::robotToSend( const Robot& robot)
{
	float tabl[3] = { robot.getX(), robot.getY(), robot.getAngle() };
	char *message = new char[ sizeof(float)*3 + 1];
	message[0] = '1';
	char *courant = (char*)tabl;

	for( unsigned int i = 1; i <= sizeof(float)*3 ; i++)
	{
		message[i] = *(courant+i -1);
	}
	return message;
}

char *LIVIATcp_server::gridToSend(const vector<XYGrid> grid)
{
	char *message = new char[sizeof(GRID)*grid.size() + 1 + sizeof(int)];
	message[0] = '2';
	stringstream is;
	int size = grid.size();
	char *taille = (char*)size;

	for( int i = 0; i < sizeof(int); i++ )
	{
		message[i + 1] = *(taille+i);
 	}

	char *courant;
	XYGrid grille[size];

	for( int i = 0; i < size; i++)
	{
		grille[i] = grid.at(i);
	}

	courant = (char*)grille;

	for( unsigned int i = 0; i < sizeof(XYGrid)*grid.size(); i++)
	{
		message[i+ 2 + sizeof(int)] = *courant;
		//on copie octet par octet à la suite du message
		courant++;
	}
	return message;
}

void LIVIATcp_server::connect_data( int portData )
{
	datas.async_connect(boost::asio::ip::tcp::endpoint(address.address()
	, portData), NULL);
}

void LIVIATcp_server::handler_read(const boost::system::error_code& error, std::size_t bytes_transferred)
{
	string message;
	if( !error)
	{
		char message[bytes_transferred];
		vector<char>::iterator it = buffer.begin();
		for( unsigned int i = 0; i < bytes_transferred; i++ )
		{
			message[i] = *(it+i);
		}

		int *
		if( message[0] == 'I')
		{
			string coord = message + 1;
			int *init = (int*)(message + 1);
			int port = *init;
			connect_data( port );
			int longueur = *(init+1);
			int largeur = *(init+2);
			int posX = *(init+3);
			int posY = *(init+4);

			//todo voir ce qu'on en fait => attribut map??
		}
		else if( message[0] == 'E')
		{
			datas.close();
			control.close();
			//peut retourner 0 pour dire que la connection est terminée
		}
		buffer.clear();
	}
}
